package com.lxk.aspect;

import com.lxk.common.EventTypeEnum;
import com.lxk.common.GsonUtils;
import com.lxk.domain.dto.VisitorInfoDto;
import com.lxk.service.event.EventBusEnum;
import com.lxk.service.event.EventBusManager;
import com.lxk.service.event.domain.EventDto;
import com.lxk.utils.IpUtils;
import com.lxk.utils.RequestUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * Created by Lxk on 2020/6/11.
 */
@Aspect
@Component
public class LogAspect {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    EventBusManager eventBusManager;

    @Pointcut("execution(* com.lxk.controller.*.*(..))")
    public void log(){
    }

    @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String url = request.getRequestURL().toString();
        String ip = IpUtils.getIpAddress(request);
        EventDto eventDto = new EventDto();
        eventDto.setEventType(EventTypeEnum.EVENT_VISITOR_COME);
        VisitorInfoDto visitorInfoDto = new VisitorInfoDto();
        visitorInfoDto.setVisitIp(ip);
        visitorInfoDto.setVisitPath(url);
        visitorInfoDto.setVisitTime(LocalDateTime.now().toString());
        eventDto.setContent(GsonUtils.getGson().toJson(visitorInfoDto));
        eventBusManager.get(EventBusEnum.EVENT_BUS_PUBLISH).post(eventDto);
        String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        RequestInfo requestInfo = new RequestInfo(url,ip,classMethod,args);
        RequestUtils.putRequestInfo(requestInfo);
        logger.info(" ====== Request:{}",requestInfo);
    }

    @AfterReturning(returning = "result",pointcut = "log()")
    public void afterReturn(Object result){
        logger.info(" ======= Result:{}",result);
        RequestUtils.removeRequestInfo();
    }

    @AfterThrowing(pointcut = "log()")
    public void afterThrowing(){
        logger.info(" ======= ex occur");
        RequestUtils.removeRequestInfo();
    }

}
